package com.yinuo.face;

import com.arcsoft.face.*;
import com.arcsoft.face.enums.DetectMode;
import com.arcsoft.face.enums.DetectOrient;
import com.arcsoft.face.enums.ErrorInfo;
import com.arcsoft.face.toolkit.ImageInfo;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class ArcSoftFaceEngine {
    //从官网获取
    String appId = "FudyiL4JVE9G9WWb6N4Y3Q5ruvZv2eGBYbYsLVFkT2XV";
    String sdkKey = "4p2fCzsH1fxF3Weyvp9NX3e1c3fDE85drrfG4F5QJPLV";

    List<FaceInfo> faceInfoList = new ArrayList<>();

    private FaceEngine faceEngine;

    public void init(){
        faceEngine = new FaceEngine(new File("dll\\WIN64").getAbsolutePath());
        //激活引擎
        int errorCode = faceEngine.activeOnline(appId, sdkKey);

        if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
            throw new ArcSoftFaceException("引擎激活失败");
        }


        ActiveFileInfo activeFileInfo=new ActiveFileInfo();
        errorCode = faceEngine.getActiveFileInfo(activeFileInfo);
        if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
            throw new ArcSoftFaceException("获取激活文件信息失败");
        }

        //引擎配置
        EngineConfiguration engineConfiguration = new EngineConfiguration();
        engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
        engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_0_ONLY);
        engineConfiguration.setDetectFaceMaxNum(10);
        engineConfiguration.setDetectFaceScaleVal(16);
        //功能配置
        FunctionConfiguration functionConfiguration = new FunctionConfiguration();
        functionConfiguration.setSupportFace3dAngle(true);
        functionConfiguration.setSupportFaceDetect(true);
        functionConfiguration.setSupportFaceRecognition(true);
        engineConfiguration.setFunctionConfiguration(functionConfiguration);


        //初始化引擎
        errorCode = faceEngine.init(engineConfiguration);

        if (errorCode != ErrorInfo.MOK.getValue()) {
            throw new ArcSoftFaceException("初始化引擎失败");
        }
    }

    public Optional<FaceInfo> detect(ImageInfo imageInfo) {
        if(imageInfo == null){
            return Optional.empty();
        }
        faceInfoList.clear();
        int errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);
        if(errorCode == ErrorInfo.MOK.getValue() && faceInfoList.size() > 0){
            return Optional.of(faceInfoList.get(0));
        }

        return Optional.empty();
    }

    public Optional<Face3DAngle> face3D(ImageInfo imageInfo) {
        if(imageInfo == null || faceInfoList.size() == 0){
            return Optional.empty();
        }
        int processCode = faceEngine.process(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList, FunctionConfiguration.builder().supportFace3dAngle(true).build());
        if(processCode != ErrorInfo.MOK.getValue()){
            return Optional.empty();
        }
        List<Face3DAngle> face3DAngles = new ArrayList<>();
        int face3DAngleCode = faceEngine.getFace3DAngle(face3DAngles);
        if(face3DAngleCode != ErrorInfo.MOK.getValue()){
            return Optional.empty();
        }
        return Optional.of(face3DAngles.get(0));
    }
}
